<template>
  <div class="menu-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>菜单管理</span>
          <el-button type="primary" @click="handleAdd">新增菜单</el-button>
        </div>
      </template>

      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="菜单名称">
          <el-input v-model="queryParams.name" placeholder="请输入菜单名称" clearable @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-select v-model="queryParams.type" placeholder="请选择菜单类型" clearable>
            <el-option v-for="item in menuTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="显示状态">
          <el-select v-model="queryParams.visible" placeholder="请选择显示状态" clearable>
            <el-option v-for="item in visibleOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <el-table
        v-loading="loading"
        :data="menuList"
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        border
      >
        <el-table-column prop="name" label="菜单名称" width="180" />
        <el-table-column prop="icon" label="图标" width="100">
          <template #default="scope">
            <el-icon v-if="scope.row.icon">
              <component :is="scope.row.icon" />
            </el-icon>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="path" label="路由地址" />
        <el-table-column prop="component" label="组件路径" />
        <el-table-column prop="permission" label="权限标识" />
        <el-table-column prop="type" label="类型" width="80">
          <template #default="scope">
            <el-tag v-if="scope.row.type === 1" type="success">目录</el-tag>
            <el-tag v-else-if="scope.row.type === 2" type="primary">菜单</el-tag>
            <el-tag v-else-if="scope.row.type === 3" type="warning">按钮</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="sort" label="排序" width="80" />
        <el-table-column prop="visible" label="显示状态" width="80">
          <template #default="scope">
            <el-tag v-if="scope.row.visible === 1" type="success">显示</el-tag>
            <el-tag v-else type="info">隐藏</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180">
          <template #default="scope">
            <el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
            <el-button type="primary" link @click="handleAdd(scope.row)">新增</el-button>
            <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 菜单表单对话框 -->
    <el-dialog
      :title="dialog.title"
      v-model="dialog.visible"
      width="600px"
      append-to-body
      @close="resetForm"
    >
      <el-form
        ref="menuFormRef"
        :model="menuForm"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="上级菜单">
          <el-tree-select
            v-model="menuForm.parentId"
            :data="menuOptions"
            :props="{ label: 'name', value: 'id', children: 'children' }"
            value-key="id"
            placeholder="请选择上级菜单"
            check-strictly
            clearable
          />
        </el-form-item>
        <el-form-item label="菜单类型" prop="type">
          <el-radio-group v-model="menuForm.type">
            <el-radio v-for="item in menuTypeOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="menuForm.name" placeholder="请输入菜单名称" />
        </el-form-item>
        <el-form-item label="菜单图标" v-if="menuForm.type !== 3">
          <el-input v-model="menuForm.icon" placeholder="请输入菜单图标" />
        </el-form-item>
        <el-form-item label="路由地址" prop="path" v-if="menuForm.type !== 3">
          <el-input v-model="menuForm.path" placeholder="请输入路由地址" />
        </el-form-item>
        <el-form-item label="组件路径" prop="component" v-if="menuForm.type === 2">
          <el-input v-model="menuForm.component" placeholder="请输入组件路径" />
        </el-form-item>
        <el-form-item label="权限标识" prop="permission" v-if="menuForm.type !== 1">
          <el-input v-model="menuForm.permission" placeholder="请输入权限标识" />
        </el-form-item>
        <el-form-item label="显示状态" v-if="menuForm.type !== 3">
          <el-radio-group v-model="menuForm.visible">
            <el-radio v-for="item in visibleOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="菜单缓存" v-if="menuForm.type === 2">
          <el-radio-group v-model="menuForm.keepAlive">
            <el-radio v-for="item in keepAliveOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="是否外链" v-if="menuForm.type !== 3">
          <el-radio-group v-model="menuForm.external">
            <el-radio v-for="item in externalOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="menuForm.sort" :min="0" :max="999" controls-position="right" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialog.visible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
import { getMenuList, getMenuTree, getMenuDetail, createMenu, updateMenu, deleteMenu } from '@/api/system/menu';
import { Menu, MenuType, menuTypeOptions, visibleOptions, keepAliveOptions, externalOptions } from '@/types/system/menu';

// 查询参数
const queryParams = reactive({
  name: '',
  type: undefined,
  visible: undefined
});

// 菜单列表
const menuList = ref<Menu[]>([]);
// 菜单选项
const menuOptions = ref<Menu[]>([]);
// 加载状态
const loading = ref(false);

// 对话框状态
const dialog = reactive({
  visible: false,
  title: ''
});

// 菜单表单
const menuForm = reactive<Menu>({
  id: undefined,
  name: '',
  path: '',
  component: '',
  icon: '',
  parentId: 0,
  sort: 0,
  permission: '',
  type: MenuType.MENU,
  visible: 1,
  keepAlive: 0,
  external: 0
});

// 表单校验规则
const rules = {
  name: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
  type: [{ required: true, message: '菜单类型不能为空', trigger: 'change' }],
  path: [
    { 
      required: true, 
      message: '路由地址不能为空', 
      trigger: 'blur',
      validator: (_: any, value: string, callback: Function) => {
        if (menuForm.type !== MenuType.BUTTON && !value) {
          callback(new Error('路由地址不能为空'));
        } else {
          callback();
        }
      }
    }
  ],
  component: [
    { 
      required: true, 
      message: '组件路径不能为空', 
      trigger: 'blur',
      validator: (_: any, value: string, callback: Function) => {
        if (menuForm.type === MenuType.MENU && !value) {
          callback(new Error('组件路径不能为空'));
        } else {
          callback();
        }
      }
    }
  ]
};

// 表单引用
const menuFormRef = ref<FormInstance>();

// 获取菜单列表
const getList = async () => {
  loading.value = true;
  try {
    const res = await getMenuTree(queryParams);
    menuList.value = res.data || [];
  } catch (error) {
    console.error('获取菜单列表失败', error);
  } finally {
    loading.value = false;
  }
};

// 获取菜单选项
const getMenuOptions = async () => {
  try {
    const res = await getMenuTree();
    // 添加顶级菜单选项
    const rootMenu: Menu = { id: 0, name: '顶级菜单', type: 0 };
    menuOptions.value = [rootMenu, ...(res.data || [])];
  } catch (error) {
    console.error('获取菜单选项失败', error);
  }
};

// 查询
const handleQuery = () => {
  getList();
};

// 重置查询
const resetQuery = () => {
  queryParams.name = '';
  queryParams.type = undefined;
  queryParams.visible = undefined;
  handleQuery();
};

// 重置表单
const resetForm = () => {
  if (menuFormRef.value) {
    menuFormRef.value.resetFields();
  }
  menuForm.id = undefined;
  menuForm.name = '';
  menuForm.path = '';
  menuForm.component = '';
  menuForm.icon = '';
  menuForm.parentId = 0;
  menuForm.sort = 0;
  menuForm.permission = '';
  menuForm.type = MenuType.MENU;
  menuForm.visible = 1;
  menuForm.keepAlive = 0;
  menuForm.external = 0;
};

// 新增菜单
const handleAdd = (row?: Menu) => {
  resetForm();
  dialog.title = '新增菜单';
  dialog.visible = true;
  if (row && row.id) {
    menuForm.parentId = row.id;
  }
};

// 编辑菜单
const handleEdit = async (row: Menu) => {
  resetForm();
  dialog.title = '编辑菜单';
  dialog.visible = true;
  try {
    const res = await getMenuDetail(row.id!);
    Object.assign(menuForm, res.data);
  } catch (error) {
    console.error('获取菜单详情失败', error);
  }
};

// 删除菜单
const handleDelete = (row: Menu) => {
  ElMessageBox.confirm(`确认删除菜单 ${row.name} 吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      await deleteMenu(row.id!);
      ElMessage.success('删除成功');
      getList();
    } catch (error) {
      console.error('删除菜单失败', error);
    }
  }).catch(() => {});
};

// 提交表单
const submitForm = async () => {
  if (!menuFormRef.value) return;
  
  await menuFormRef.value.validate(async (valid) => {
    if (!valid) return;
    
    try {
      if (menuForm.id) {
        // 更新菜单
        await updateMenu(menuForm);
        ElMessage.success('更新成功');
      } else {
        // 创建菜单
        await createMenu(menuForm);
        ElMessage.success('创建成功');
      }
      dialog.visible = false;
      getList();
    } catch (error) {
      console.error('保存菜单失败', error);
    }
  });
};

onMounted(() => {
  getList();
  getMenuOptions();
});
</script>

<style scoped>
.menu-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-form {
  margin-bottom: 20px;
}
</style> 